package cn.org.rookie.jeesdp.encryption;

import cn.org.rookie.jeesdp.core.utils.AESUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author LHT
 * @date 2022-10-03 19:03
 */

public class EncryptionPostProcessor implements EnvironmentPostProcessor {

    private final Pattern pattern = Pattern.compile("(?<=cipher).*?(?=\\))");

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        if (Boolean.TRUE.equals(environment.getProperty("jeesdp.encrypt", Boolean.class))) {
            MutablePropertySources propertySources = environment.getPropertySources();
            for (PropertySource<?> item : propertySources) {
                if (item instanceof OriginTrackedMapPropertySource propertySource) {
                    String[] names = propertySource.getPropertyNames();
                    Map<String, Object> config = new LinkedHashMap<>();
                    for (String name : names) {
                        Object property = propertySource.getProperty(name);
                        String restlt = null;
                        if (property instanceof String value) {
                            restlt = value;
                        } else if (property instanceof Integer value) {
                            restlt = String.valueOf(value);
                        }
                        if (restlt != null) {
                            Matcher matcher = pattern.matcher(restlt);
                            if (matcher.find()) {
                                config.put(name, AESUtils.decrypt(matcher.group()));
                            } else {
                                config.put(name, restlt);
                            }
                        } else {
                            config.put(name, property);
                        }
                    }
                    String propertySourceName = propertySource.getName();
                    propertySources.replace(propertySourceName, new OriginTrackedMapPropertySource(propertySourceName, config));
                }
            }
        }
    }
}

